x86: Cleanup system restart code, and wait 10ms for APs to offline.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Mon, 10 Sep 2007 17:09:38 +0000 (18:09 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Mon, 10 Sep 2007 17:09:38 +0000 (18:09 +0100)
Signed-off-by: Joseph Cihula <joseph.cihula@intel.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/machine_kexec.c
xen/arch/x86/shutdown.c
xen/arch/x86/smp.c

index 8fbd1ab164092e9c6b1d2e46ae166be310598bd9..5d693a29388c74fbb1276999f2fbeb5ee54738bd 100644 (file)
@@ -82,9 +82,6 @@ static void __machine_reboot_kexec(void *data)
 
     smp_send_stop();
 
-    disable_IO_APIC();
-    hvm_cpu_down();
-
     machine_kexec(image);
 }
 
index 8bc658fa8348e0db6fe51df09450d9520eea0b13..7653dce4fd4988b16d59e5aca3987815675f8e41 100644 (file)
@@ -216,18 +216,12 @@ void machine_restart(void)
             safe_halt();
     }
 
-    /*
-     * Stop all CPUs and turn off local APICs and the IO-APIC, so
-     * other OSs see a clean IRQ state.
-     */
     smp_send_stop();
-    disable_IO_APIC();
-    hvm_cpu_down();
 
     /* Rebooting needs to touch the page at absolute address 0. */
     *((unsigned short *)__va(0x472)) = reboot_mode;
 
-    if (reboot_thru_bios <= 0)
+    if ( reboot_thru_bios <= 0 )
     {
         for ( ; ; )
         {
index 1d83a3aba36f831b535c43ed4176bea7817cee37..550faf069be443c745459be9b8a71432bb572419 100644 (file)
@@ -319,23 +319,33 @@ int on_selected_cpus(
 
 static void stop_this_cpu (void *dummy)
 {
-    cpu_clear(smp_processor_id(), cpu_online_map);
-
-    local_irq_disable();
     disable_local_APIC();
     hvm_cpu_down();
 
+    cpu_clear(smp_processor_id(), cpu_online_map);
+
     for ( ; ; )
         __asm__ __volatile__ ( "hlt" );
 }
 
+/*
+ * Stop all CPUs and turn off local APICs and the IO-APIC, so other OSs see a 
+ * clean IRQ state.
+ */
 void smp_send_stop(void)
 {
-    /* Stop all other CPUs in the system. */
+    int timeout = 10;
+
     smp_call_function(stop_this_cpu, NULL, 1, 0);
 
+    /* Wait 10ms for all other CPUs to go offline. */
+    while ( (num_online_cpus() > 1) && (timeout-- > 0) )
+        mdelay(1);
+
     local_irq_disable();
     disable_local_APIC();
+    disable_IO_APIC();
+    hvm_cpu_down();
     local_irq_enable();
 }